<!-- 树形复选框列表 -->
<template>
		<view  :style="{height:getHeight+'px','overflow':'scroll'}">
			<view class="" v-for="(node, index) in treeList" :key="node.key" :index="index">
				<transition name="fade">
					<view @click.stop="toggleTree(!isOpen(node.key), node,'click')"
						v-show="node.show || node.rank === 0">
						<view style="display: flex;flex-direction: row;" class="tree-node">
							<view v-if="node.childrenid && node.childrenid.length > 0">
								<uni-icons customPrefix="iconfont" style="text-align: center;"
									:style="{ marginLeft: `${node.rank * 30}rpx` }"
									:type="node.open ? 'layui-icon-triangle-d' : 'layui-icon-triangle-r'" size="19">
								</uni-icons>
							</view>
							<table-checkbox v-if="isCheckBox"
								:style="{ marginLeft: !node.childrenid ? `${48 + node.rank * 30}rpx` : '10rpx' }"
								:checked="node.checked" v-model="node.checked" :indeterminate="node.indeterminate"
								:disabled="disabled" @checkboxSelected="checkboxSelected" :cellData="node">
							</table-checkbox>
							<text
								:style="{ marginLeft: (!node.childrenid&&!isCheckBox) ? `${48 + node.rank * 30}rpx` : '10rpx' }">{{ node.name }}</text>
						</view>
					</view>
				</transition>
			</view>
		</view>
</template>

<script>
	import * as SystemJs from '@/common/system.js'
	import tableCheckbox from './table-checkbox.vue'
	export default {
		name: "treeItem",
		components: {
			tableCheckbox
		},
		emits: ['checkSelected', 'nodeClick'],
		props: {
			//显示数据列表
			treeData: {
				type: Array,
				default: []
			},
			//默认选中节点列表
			defaultCheckedList: {
				type: Array,
				default: []
			},
			//是否显示复选框可多选
			isCheckBox: {
				type: [Boolean, String],
				default: true
			},
			height: {
				type: [Number, String],
				default: 0
			}
		},
		watch: {
			//数据变化监听事件
			treeData(newVal) {
				this.$nextTick(() => {
					this.loadTree()
				})
			},
			defaultCheckedList(newVal) {
				this.$nextTick(() => {
					this.defaultCheckNode()
				})
			}
		},
		mounted() {
			this.$nextTick(() => {
				this.loadTree()
			})
		},
		data() {
			return {
				value: false,
				border: false,
				selection: false,
				widthThArr: [],
				ishead: true,
				checked: false,
				indeterminate: false, //父节点未全部选择的状态
				// treeData: [{
				// 		name: '1',
				// 		key: '1',
				// 		children: [{
				// 				name: '1-1',
				// 				key: '1-1',
				// 				children: [{
				// 					name: '1-11',
				// 					key: '1-11',
				// 					children: []
				// 				}]
				// 			},
				// 			{
				// 				name: '1-2',
				// 				key: '1-2',
				// 				children: []
				// 			}
				// 		]
				// 	},
				// 	{
				// 		name: '2',
				// 		key: '2',
				// 		children: [{
				// 				name: '2-1',
				// 				key: '2-1',
				// 				children: []
				// 			},
				// 			{
				// 				name: '2-2',
				// 				key: '2-2',
				// 				children: []
				// 			}
				// 		]
				// 	}
				// ],
				treeList: [], //显示平铺数据列表
				openedList: [], //打开状态父节点的列表
				// defaultCheckedList: ['1-2'],
				showList: [], //显示状态的节点列表
				checkInfos: [], //勾选子节点数据列表
				defaultOpenedKeys: [],
				checkedList: []
			};
		},
		computed: {
			getHeight(){
				if(SystemJs.systemJs.IsEmpty(this.height+"")||Number(this.height)<=0){
					return '';
				}else{
					return this.height
				}
			},
			// 判断节点展开/关闭
			isOpen() {
				return function(key) {
					return this.openedList.includes(key);
				};
			},
			// 判断节点显示/隐藏
			// isShow() {
			// 	return function(key) {
			// 		return this.showList.includes(key);
			// 	};
			// }

		},
		methods: {
			// 初始化树方法，可在初始化及reload刷新时调用重新渲染树结构
			loadTree() {
				this.resetData()
				this.renderTreeList();
			},
			resetData() {
				this.openedList = []
				this.checkedList = []
				this.checkInfos = []
				this.treeList = []
				this.showList = []
			},
			renderTreeList() {
				if (this.treeData != undefined && this.treeData.length > 0) {
					for (var i = 0; i < this.treeData.length; i++) {
						var temList = [];
						var temTree = this.treeData[i];
						var obj = {};
						if (temTree) {
							var list = [].concat(temTree);
							var parentId = [];
							var childrenId = [];
							this.createTree(list, 0, temList, parentId, childrenId);
							this.treeList = this.treeList.concat(temList);
							// console.log(this.treeList)
						}
					}
					//执行默认选中的节点
					this.defaultCheckNode();
					// console.log(this.checkInfos)
				}
			},
			/**
			 * 创建平铺数组节点数据
			 * @param {Object} treeData
			 * @param {Object} rank
			 * @param {Object} temList
			 * @param {Object} parentId
			 * @param {Object} childrenId
			 */
			createTree(treeData, rank, temList, parentId, childrenId) {
				// var temList = [];
				var tparentId = [];
				if (treeData != undefined && treeData.length > 0) {
					for (var i = 0; i < treeData.length; i++) {
						var temTree = JSON.parse(JSON.stringify(treeData[i]));
						var obj = {};
						if (temTree) {
							if (childrenId != undefined && rank > 0 && !childrenId.includes(temTree.key)) {
								childrenId.push(temTree.key)
							}
							if (rank > 0) {
								obj.parentId = parentId.concat();
							}
							obj.key = temTree.key;
							obj.name = temTree.name;
							obj.rank = rank; //级别
							obj.checked = false; //是否选中
							obj.indeterminate = false; //父节点是否有子节点勾选
							obj.show = false; //是否显示
							obj.open = false; //父节点是否打开
							if (temTree.children != undefined && temTree.children.length > 0) {
								if (tparentId != undefined && !tparentId.includes(temTree.key)) {
									tparentId.push(temTree.key)
								}
								var tchildrenId = [];
								obj.children = temTree.children;
								var r = rank + 1;
								this.createTree(temTree.children, r, temList, tparentId, tchildrenId)
								// temList.concat(list)
								obj.childrenid = tchildrenId;
								temList.splice(0, 0, obj);
							} else {
								temList.push(obj);
							}

						}
					}
				}
			},
			/**
			 * 默认选中操作（勾选上提前默认勾选的节点）
			 */
			defaultCheckNode() {
				if (this.defaultCheckedList && this.defaultCheckedList.length > 0) {
					var parentIdList = [];
					this.defaultCheckedList.forEach((x) => {
						const node = this.treeList.find(n => n.key === x);
						if (!node.checked) {
							node.checked = true;
							this.getAllCheckedInfo(node);
							this.changeParentNode(node)
							//new Set()使用该函数进行数组的去重操作
							parentIdList = [...new Set([...this.generationKeysP(node.parentId, this.treeList), ...
								parentIdList
							])]
							var childrenList = [...new Set(this.generationKeys(node.childrenid, this.treeList))]
							if (childrenList && childrenList.length > 0) {
								childrenList.forEach((c) => {
									const childNode = this.treeList.find(n => n.key === c);
									parentIdList = [...new Set([...this.generationKeysP(childNode
											.parentId, this.treeList), ...
										parentIdList
									])]
								})
							}
						}
					})
					//打开选中的所有父节点的列表
					if (parentIdList && parentIdList.length > 0) {
						parentIdList.forEach((p) => {
							const parentNode = this.treeList.find(n => n.key === p);
							this.toggleTree(true, parentNode)
						})
					}
				}
			},
			// 深度遍历，如果有子级则逐层取出子级的key
			generationKeys(childrenid, treeList) {
				let checkedKeys = [];
				const deepEach = (ids, list) => {
					if (ids && ids.length > 0) {
						ids.forEach(id => {
							const childNode = list.find(node => node.key === id);
							if (childNode && childNode.childrenid && childNode.childrenid.length > 0) {
								deepEach(childNode.childrenid, list);
								checkedKeys = [...checkedKeys, ...childNode.childrenid, id];
							} else {
								checkedKeys = [...checkedKeys, id];
							}
						});
					}
				};
				deepEach(childrenid, treeList);
				return checkedKeys;
			},
			// 深度遍历，如果有子级则逐层取出父级的key
			generationKeysP(parentId, treeList) {
				let checkedKeys = [];
				const deepEach = (ids, list) => {
					if (ids && ids.length > 0) {
						ids.forEach(id => {
							const parentNode = list.find(node => node.key === id);
							if (parentNode && parentNode.parentId && parentNode.parentId.length > 0) {
								deepEach(parentNode.parentId, list);
								checkedKeys = [id, ...checkedKeys, ...parentNode.parentId];
								// console.log(checkedKeys)
							} else {
								checkedKeys = [id, ...checkedKeys];
							}
						});
					}
				};
				deepEach(parentId, treeList);
				return checkedKeys;
			},
			// 节点关闭打开事件
			toggleTree(opened, node, type = "") {
				const openedList = this.openedList;
				// console.log(opened)
				if (!opened) {
					var temp = this.treeList.find(item => item.key === node.key)
					temp.open = false;
					this.openedList = [...this.delItemInArr(openedList, node.key)];
					const closed = [...new Set(this.generationKeys(node.childrenid, this.treeList))];
					// 关闭时先遍历有没有存在子级的节点，如果有则级联关闭
					closed.forEach(x => {
						const childNode = this.treeList.find(node => node.key === x);
						if (childNode && childNode.childrenid) {
							this.openedList = [...this.delItemInArr(this.openedList, childNode.key)];
							childNode.open = false;
						}
						// var temp = this.treeList.find(item => item.key === x)
						childNode.show = false;
						// // 将关闭节点的子级全部隐藏
						this.showList = this.showList.filter(k => k !== x);
					});
				} else {
					// 打开时显示所有子级节点
					this.openedList.push(node.key);
					if (node.childrenid && node.childrenid.length > 0) {
						this.showList = [...new Set([...this.openedList, ...this.showList, ...node.childrenid])];
					} else {
						this.showList = [...new Set([...this.openedList, ...this.showList])];
					}
					this.showList.forEach((key, index) => {
						var temp = this.treeList.find(item => item.key === key)
						temp.show = true;
					})
					this.openedList.forEach((key, index) => {
						var temp = this.treeList.find(item => item.key === key)
						temp.open = true;
					})
				}
				//没有复选框选择功能时，允许触发节点点击事件
				if (!this.isCheckBox && type == 'click') {
					var obj = {};
					obj.key = node.key;
					obj.name = node.name;
					this.$emit('nodeClick', {
						node: obj
					})
				}
			},
			// 删除数组中指定子项方法
			delItemInArr(arr, item) {
				const newArr = arr;
				const index = newArr.findIndex(p => p === item);
				if (index >= 0) {
					newArr.splice(index, 1);
				}
				return newArr;
			},
			/**
			 * 勾选复选框事件
			 * @param {Object} e
			 */
			checkboxSelected(e) {
				var node = e.data; //获取勾选节点的数据
				var checked = e.checked;
				this.getAllCheckedInfo(node);
				this.changeParentNode(node)
				var obj = {};
				obj.key = node.key;
				obj.name = node.name;
				obj.checked = node.checked;
				this.$emit("checkSelected", {
					node: obj,
					data: this.checkInfos
				})
			},

			/**
			 * 获取所有勾选的数据
			 * @param {Object} node
			 */
			getAllCheckedInfo(node) {
				//判定子节点
				if (node.childrenid != undefined && node.childrenid.length > 0) {
					const children = [...new Set(this.generationKeys(node.childrenid, this.treeList))];
					if (children != undefined && children.length > 0) {
						children.forEach(x => {
							const childNode = this.treeList.find(node => node.key === x);
							childNode.checked = node.checked;
							if (node.checked && (childNode.childrenid == undefined || childNode.childrenid.length <
									1)) {
								this.checkInfos.push(childNode.key);
								this.checkInfos = [...new Set(this.checkInfos)]
							} else {
								this.delItemInArr(this.checkInfos, childNode.key)
							}
						});
					}
				}
				if (node.checked && (node.childrenid == undefined || node.childrenid.length < 1)) {
					this.checkInfos.push(node.key);
					this.checkInfos = [...new Set(this.checkInfos)]
				} else {
					this.delItemInArr(this.checkInfos, node.key)
				}
			},
			/**
			 * 判断改变父节点的状态
			 * @param {Object} node
			 */
			changeParentNode(node) {
				//判定父节点
				var d = [...new Set(this.generationKeysP(node.parentId, this.treeList))];
				if (d != undefined && d.length > 0) {
					d.forEach((p) => {
						var allChecked = true; //是否全部勾选
						var allNoChecked = true; //是否全部未勾选
						var parent = this.treeList.find(x => x.key === p)
						var children = [...new Set(this.generationKeys(parent.childrenid, this.treeList))];
						if (children != undefined && children.length > 0) {
							children.forEach((c) => {
								var childNode = this.treeList.find(item => item.key === c)
								if (childNode != undefined) {
									if (!childNode.checked) {
										allChecked = false;
									}
									if (childNode.checked) {
										allNoChecked = false;
									}
								}
							})
						}
						if (allChecked) {
							parent.checked = true;
							parent.indeterminate = false;
						} else {
							if (allNoChecked) {
								parent.checked = false;
								parent.indeterminate = false;
							} else {
								parent.checked = false;
								parent.indeterminate = true;
							}
						}
					})
				}
			}

		}
	}
</script>

<style scoped>
	.checkbox-item {
		padding-left: 8rpx;

		/* /deep/ .u-checkbox__label {
			margin-right: 0;
		} */
	}

	.tree-node {
		margin-bottom: 8rpx;
	}
</style>
